
#ifndef __HOOK_SECHOST_H__
#define __HOOK_SECHOST_H__

#include "base.h"

int Hook_Sechost();
int UnHook_Sechost();

int Hook_Advapi32();
int UnHook_Advapi32();

int Hook_Rpcrt4();
int UnHook_Rpcrt4();

CLIENT_CALL_RETURN RPC_VAR_ENTRY HOOK_NdrClientCall2(
    PMIDL_STUB_DESC pStubDescriptor, 
    PFORMAT_STRING pFormat, ...);
typedef CLIENT_CALL_RETURN(RPC_VAR_ENTRY* PFN_NdrClientCall2)(
    PMIDL_STUB_DESC pStubDescriptor, PFORMAT_STRING pFormat, ...);
extern PFN_NdrClientCall2 REAL_NdrClientCall2;

SC_HANDLE WINAPI HOOK_OpenSCManagerA(
    _In_opt_        LPCSTR                lpMachineName,
    _In_opt_        LPCSTR                lpDatabaseName,
    _In_            DWORD                 dwDesiredAccess);
typedef SC_HANDLE(WINAPI* PFN_OpenSCManagerA)(
    _In_opt_        LPCSTR                lpMachineName,
    _In_opt_        LPCSTR                lpDatabaseName,
    _In_            DWORD                 dwDesiredAccess);
extern PFN_OpenSCManagerA REAL_OpenSCManagerA;

SC_HANDLE WINAPI HOOK_OpenSCManagerW(
    _In_opt_        LPCWSTR                lpMachineName,
    _In_opt_        LPCWSTR                lpDatabaseName,
    _In_            DWORD                   dwDesiredAccess);
typedef SC_HANDLE (WINAPI* PFN_OpenSCManagerW)(
    _In_opt_        LPCWSTR                lpMachineName,
    _In_opt_        LPCWSTR                lpDatabaseName,
    _In_            DWORD                   dwDesiredAccess);
extern PFN_OpenSCManagerW REAL_OpenSCManagerW;

SC_HANDLE WINAPI HOOK_OpenServiceA(
    _In_            SC_HANDLE               hSCManager,
    _In_            LPCSTR                lpServiceName,
    _In_            DWORD                   dwDesiredAccess);
typedef SC_HANDLE (WINAPI* PFN_OpenServiceA)(
    _In_            SC_HANDLE               hSCManager,
    _In_            LPCSTR                lpServiceName,
    _In_            DWORD                   dwDesiredAccess);
extern PFN_OpenServiceA REAL_OpenServiceA;

SC_HANDLE WINAPI HOOK_OpenServiceW(
    _In_            SC_HANDLE               hSCManager,
    _In_            LPCWSTR                lpServiceName,
    _In_            DWORD                   dwDesiredAccess);
typedef SC_HANDLE (WINAPI* PFN_OpenServiceW)(
    _In_            SC_HANDLE               hSCManager,
    _In_            LPCWSTR                lpServiceName,
    _In_            DWORD                   dwDesiredAccess);
extern PFN_OpenServiceW REAL_OpenServiceW;

BOOL WINAPI HOOK_StartServiceA(
    _In_            SC_HANDLE            hService,
    _In_            DWORD                dwNumServiceArgs,
    _In_reads_opt_(dwNumServiceArgs)
    LPCSTR* lpServiceArgVectors);
typedef BOOL (WINAPI* PFN_StartServiceA)(
    _In_            SC_HANDLE            hService,
    _In_            DWORD                dwNumServiceArgs,
    _In_reads_opt_(dwNumServiceArgs)
    LPCSTR* lpServiceArgVectors);
extern PFN_StartServiceA REAL_StartServiceA;

BOOL WINAPI HOOK_StartServiceW(
    _In_            SC_HANDLE            hService,
    _In_            DWORD                dwNumServiceArgs,
    _In_reads_opt_(dwNumServiceArgs)
    LPCWSTR* lpServiceArgVectors);
typedef BOOL (WINAPI* PFN_StartServiceW)(
    _In_            SC_HANDLE            hService,
    _In_            DWORD                dwNumServiceArgs,
    _In_reads_opt_(dwNumServiceArgs)
    LPCWSTR* lpServiceArgVectors);
extern PFN_StartServiceW REAL_StartServiceW;

SC_HANDLE WINAPI HOOK_CreateServiceA(
    _In_        SC_HANDLE    hSCManager,
    _In_        LPCSTR     lpServiceName,
    _In_opt_    LPCSTR     lpDisplayName,
    _In_        DWORD        dwDesiredAccess,
    _In_        DWORD        dwServiceType,
    _In_        DWORD        dwStartType,
    _In_        DWORD        dwErrorControl,
    _In_opt_    LPCSTR     lpBinaryPathName,
    _In_opt_    LPCSTR     lpLoadOrderGroup,
    _Out_opt_   LPDWORD      lpdwTagId,
    _In_opt_    LPCSTR     lpDependencies,
    _In_opt_    LPCSTR     lpServiceStartName,
    _In_opt_    LPCSTR     lpPassword);

typedef SC_HANDLE (WINAPI* PFN_CreateServiceA)(
    _In_        SC_HANDLE    hSCManager,
    _In_        LPCSTR     lpServiceName,
    _In_opt_    LPCSTR     lpDisplayName,
    _In_        DWORD        dwDesiredAccess,
    _In_        DWORD        dwServiceType,
    _In_        DWORD        dwStartType,
    _In_        DWORD        dwErrorControl,
    _In_opt_    LPCSTR     lpBinaryPathName,
    _In_opt_    LPCSTR     lpLoadOrderGroup,
    _Out_opt_   LPDWORD      lpdwTagId,
    _In_opt_    LPCSTR     lpDependencies,
    _In_opt_    LPCSTR     lpServiceStartName,
    _In_opt_    LPCSTR     lpPassword);
extern PFN_CreateServiceA REAL_CreateServiceA;

SC_HANDLE WINAPI HOOK_CreateServiceW(
    _In_        SC_HANDLE    hSCManager,
    _In_        LPCWSTR     lpServiceName,
    _In_opt_    LPCWSTR     lpDisplayName,
    _In_        DWORD        dwDesiredAccess,
    _In_        DWORD        dwServiceType,
    _In_        DWORD        dwStartType,
    _In_        DWORD        dwErrorControl,
    _In_opt_    LPCWSTR     lpBinaryPathName,
    _In_opt_    LPCWSTR     lpLoadOrderGroup,
    _Out_opt_   LPDWORD      lpdwTagId,
    _In_opt_    LPCWSTR     lpDependencies,
    _In_opt_    LPCWSTR     lpServiceStartName,
    _In_opt_    LPCWSTR     lpPassword);

typedef SC_HANDLE (WINAPI* PFN_CreateServiceW)(
    _In_        SC_HANDLE    hSCManager,
    _In_        LPCWSTR     lpServiceName,
    _In_opt_    LPCWSTR     lpDisplayName,
    _In_        DWORD        dwDesiredAccess,
    _In_        DWORD        dwServiceType,
    _In_        DWORD        dwStartType,
    _In_        DWORD        dwErrorControl,
    _In_opt_    LPCWSTR     lpBinaryPathName,
    _In_opt_    LPCWSTR     lpLoadOrderGroup,
    _Out_opt_   LPDWORD      lpdwTagId,
    _In_opt_    LPCWSTR     lpDependencies,
    _In_opt_    LPCWSTR     lpServiceStartName,
    _In_opt_    LPCWSTR     lpPassword);
extern PFN_CreateServiceW REAL_CreateServiceW;

BOOL WINAPI HOOK_ChangeServiceConfigA(
    _In_        SC_HANDLE    hService,
    _In_        DWORD        dwServiceType,
    _In_        DWORD        dwStartType,
    _In_        DWORD        dwErrorControl,
    _In_opt_    LPCSTR     lpBinaryPathName,
    _In_opt_    LPCSTR     lpLoadOrderGroup,
    _Out_opt_   LPDWORD      lpdwTagId,
    _In_opt_    LPCSTR     lpDependencies,
    _In_opt_    LPCSTR     lpServiceStartName,
    _In_opt_    LPCSTR     lpPassword,
    _In_opt_    LPCSTR     lpDisplayName);
typedef BOOL (WINAPI* PFN_ChangeServiceConfigA)(
    _In_        SC_HANDLE    hService,
    _In_        DWORD        dwServiceType,
    _In_        DWORD        dwStartType,
    _In_        DWORD        dwErrorControl,
    _In_opt_    LPCSTR     lpBinaryPathName,
    _In_opt_    LPCSTR     lpLoadOrderGroup,
    _Out_opt_   LPDWORD      lpdwTagId,
    _In_opt_    LPCSTR     lpDependencies,
    _In_opt_    LPCSTR     lpServiceStartName,
    _In_opt_    LPCSTR     lpPassword,
    _In_opt_    LPCSTR     lpDisplayName);
extern PFN_ChangeServiceConfigA REAL_ChangeServiceConfigA;

BOOL WINAPI HOOK_ChangeServiceConfigW(
    _In_        SC_HANDLE    hService,
    _In_        DWORD        dwServiceType,
    _In_        DWORD        dwStartType,
    _In_        DWORD        dwErrorControl,
    _In_opt_    LPCWSTR     lpBinaryPathName,
    _In_opt_    LPCWSTR     lpLoadOrderGroup,
    _Out_opt_   LPDWORD      lpdwTagId,
    _In_opt_    LPCWSTR     lpDependencies,
    _In_opt_    LPCWSTR     lpServiceStartName,
    _In_opt_    LPCWSTR     lpPassword,
    _In_opt_    LPCWSTR     lpDisplayName);
typedef BOOL (WINAPI* PFN_ChangeServiceConfigW)(
    _In_        SC_HANDLE    hService,
    _In_        DWORD        dwServiceType,
    _In_        DWORD        dwStartType,
    _In_        DWORD        dwErrorControl,
    _In_opt_    LPCWSTR     lpBinaryPathName,
    _In_opt_    LPCWSTR     lpLoadOrderGroup,
    _Out_opt_   LPDWORD      lpdwTagId,
    _In_opt_    LPCWSTR     lpDependencies,
    _In_opt_    LPCWSTR     lpServiceStartName,
    _In_opt_    LPCWSTR     lpPassword,
    _In_opt_    LPCWSTR     lpDisplayName);
extern PFN_ChangeServiceConfigW REAL_ChangeServiceConfigW;

BOOL WINAPI HOOK_ChangeServiceConfig2A(
    _In_           SC_HANDLE hService,
    _In_           DWORD     dwInfoLevel,
    _In_           LPVOID    lpInfo);
typedef BOOL (WINAPI* PFN_ChangeServiceConfig2A)(
    _In_           SC_HANDLE hService,
    _In_           DWORD     dwInfoLevel,
    _In_           LPVOID    lpInfo);
extern PFN_ChangeServiceConfig2A REAL_ChangeServiceConfig2A;

BOOL WINAPI HOOK_ChangeServiceConfig2W(
    _In_           SC_HANDLE hService,
    _In_           DWORD     dwInfoLevel,
    _In_           LPVOID    lpInfo);
typedef BOOL (WINAPI* PFN_ChangeServiceConfig2W)(
    _In_           SC_HANDLE hService,
    _In_           DWORD     dwInfoLevel,
    _In_           LPVOID    lpInfo);
extern PFN_ChangeServiceConfig2W REAL_ChangeServiceConfig2W;

BOOL WINAPI HOOK_QueryServiceConfigA(
    _In_            SC_HANDLE               hService,
    _Out_opt_       LPQUERY_SERVICE_CONFIGA lpServiceConfig,
    _In_            DWORD                   cbBufSize,
    _Out_           LPDWORD                 pcbBytesNeeded);
typedef BOOL (WINAPI* PFN_QueryServiceConfigA)(
    _In_            SC_HANDLE               hService,
    _Out_opt_       LPQUERY_SERVICE_CONFIGA lpServiceConfig,
    _In_            DWORD                   cbBufSize,
    _Out_           LPDWORD                 pcbBytesNeeded);
extern PFN_QueryServiceConfigA REAL_QueryServiceConfigA;

BOOL WINAPI HOOK_QueryServiceConfigW(
    _In_            SC_HANDLE               hService,
    _Out_opt_       LPQUERY_SERVICE_CONFIGW lpServiceConfig,
    _In_            DWORD                   cbBufSize,
    _Out_           LPDWORD                 pcbBytesNeeded);
typedef BOOL (WINAPI* PFN_QueryServiceConfigW)(
    _In_            SC_HANDLE               hService,
    _Out_opt_       LPQUERY_SERVICE_CONFIGW lpServiceConfig,
    _In_            DWORD                   cbBufSize,
    _Out_           LPDWORD                 pcbBytesNeeded);
extern PFN_QueryServiceConfigW REAL_QueryServiceConfigW;

BOOL WINAPI HOOK_QueryServiceConfig2A(
    _In_            SC_HANDLE hService,
    _In_            DWORD     dwInfoLevel,
    _Out_opt_       LPBYTE    lpBuffer,
    _In_            DWORD     cbBufSize,
    _Out_           LPDWORD   pcbBytesNeeded);
typedef BOOL (WINAPI* PFN_QueryServiceConfig2A)(
    _In_            SC_HANDLE hService,
    _In_            DWORD     dwInfoLevel,
    _Out_opt_       LPBYTE    lpBuffer,
    _In_            DWORD     cbBufSize,
    _Out_           LPDWORD   pcbBytesNeeded);
extern PFN_QueryServiceConfig2A REAL_QueryServiceConfig2A;

BOOL WINAPI HOOK_QueryServiceConfig2W(
    _In_            SC_HANDLE hService,
    _In_            DWORD     dwInfoLevel,
    _Out_opt_       LPBYTE    lpBuffer,
    _In_            DWORD     cbBufSize,
    _Out_           LPDWORD   pcbBytesNeeded);
typedef BOOL (WINAPI* PFN_QueryServiceConfig2W)(
    _In_            SC_HANDLE hService,
    _In_            DWORD     dwInfoLevel,
    _Out_opt_       LPBYTE    lpBuffer,
    _In_            DWORD     cbBufSize,
    _Out_           LPDWORD   pcbBytesNeeded);
extern PFN_QueryServiceConfig2W REAL_QueryServiceConfig2W;

BOOL WINAPI HOOK_QueryServiceLockStatusA(
    _In_            SC_HANDLE                    hSCManager,
    _Out_opt_       LPQUERY_SERVICE_LOCK_STATUSA lpLockStatus,
    _In_            DWORD                        cbBufSize,
    _Out_           LPDWORD                      pcbBytesNeeded);
typedef BOOL (WINAPI* PFN_QueryServiceLockStatusA)(
    _In_            SC_HANDLE                    hSCManager,
    _Out_opt_       LPQUERY_SERVICE_LOCK_STATUSA lpLockStatus,
    _In_            DWORD                        cbBufSize,
    _Out_           LPDWORD                      pcbBytesNeeded);
extern PFN_QueryServiceLockStatusA REAL_QueryServiceLockStatusA;

BOOL WINAPI HOOK_QueryServiceLockStatusW(
    _In_            SC_HANDLE                    hSCManager,
    _Out_opt_       LPQUERY_SERVICE_LOCK_STATUSW lpLockStatus,
    _In_            DWORD                        cbBufSize,
    _Out_           LPDWORD                      pcbBytesNeeded);
typedef BOOL (WINAPI* PFN_QueryServiceLockStatusW)(
    _In_            SC_HANDLE                    hSCManager,
    _Out_opt_       LPQUERY_SERVICE_LOCK_STATUSW lpLockStatus,
    _In_            DWORD                        cbBufSize,
    _Out_           LPDWORD                      pcbBytesNeeded);
extern PFN_QueryServiceLockStatusW REAL_QueryServiceLockStatusW;

BOOL WINAPI HOOK_ControlServiceExA(
    _In_       SC_HANDLE hService,
    _In_       DWORD     dwControl,
    _In_       DWORD     dwInfoLevel,
    _Inout_    PVOID     pControlParams);
typedef BOOL (WINAPI* PFN_ControlServiceExA)(
    _In_       SC_HANDLE hService,
    _In_       DWORD     dwControl,
    _In_       DWORD     dwInfoLevel,
    _Inout_    PVOID     pControlParams);
extern PFN_ControlServiceExA REAL_ControlServiceExA;

BOOL WINAPI HOOK_ControlServiceExW(
    _In_      SC_HANDLE hService,
    _In_      DWORD     dwControl,
    _In_      DWORD     dwInfoLevel,
    _Inout_   PVOID     pControlParams);
typedef BOOL (WINAPI* PFN_ControlServiceExW)(
    _In_      SC_HANDLE hService,
    _In_      DWORD     dwControl,
    _In_      DWORD     dwInfoLevel,
    _Inout_   PVOID     pControlParams);
extern PFN_ControlServiceExW REAL_ControlServiceExW;

SERVICE_STATUS_HANDLE WINAPI HOOK_RegisterServiceCtrlHandlerA(
    _In_ LPCSTR             lpServiceName,
    _In_ LPHANDLER_FUNCTION lpHandlerProc);
typedef SERVICE_STATUS_HANDLE (WINAPI* PFN_RegisterServiceCtrlHandlerA)(
    _In_ LPCSTR             lpServiceName,
    _In_ LPHANDLER_FUNCTION lpHandlerProc);
extern PFN_RegisterServiceCtrlHandlerA REAL_RegisterServiceCtrlHandlerA;

SERVICE_STATUS_HANDLE WINAPI HOOK_RegisterServiceCtrlHandlerW(
    _In_ LPCWSTR            lpServiceName,
    _In_ LPHANDLER_FUNCTION lpHandlerProc);
typedef SERVICE_STATUS_HANDLE (WINAPI* PFN_RegisterServiceCtrlHandlerW)(
    _In_ LPCWSTR            lpServiceName,
    _In_ LPHANDLER_FUNCTION lpHandlerProc);
extern PFN_RegisterServiceCtrlHandlerW REAL_RegisterServiceCtrlHandlerW;

SERVICE_STATUS_HANDLE WINAPI HOOK_RegisterServiceCtrlHandlerExA(
    _In_           LPCSTR                lpServiceName,
    _In_           LPHANDLER_FUNCTION_EX lpHandlerProc,
    _In_opt_       LPVOID                lpContext);
typedef SERVICE_STATUS_HANDLE (WINAPI* PFN_RegisterServiceCtrlHandlerExA)(
    _In_           LPCSTR                lpServiceName,
    _In_           LPHANDLER_FUNCTION_EX lpHandlerProc,
    _In_opt_       LPVOID                lpContext);
extern PFN_RegisterServiceCtrlHandlerExA REAL_RegisterServiceCtrlHandlerExA;

SERVICE_STATUS_HANDLE WINAPI HOOK_RegisterServiceCtrlHandlerExW(
    _In_           LPCWSTR               lpServiceName,
    _In_           LPHANDLER_FUNCTION_EX lpHandlerProc,
    _In_opt_       LPVOID                lpContext);
typedef SERVICE_STATUS_HANDLE (WINAPI* PFN_RegisterServiceCtrlHandlerExW)(
    _In_           LPCWSTR               lpServiceName,
    _In_           LPHANDLER_FUNCTION_EX lpHandlerProc,
    _In_opt_       LPVOID                lpContext);
extern PFN_RegisterServiceCtrlHandlerExW REAL_RegisterServiceCtrlHandlerExW;

DWORD WINAPI HOOK_NotifyServiceStatusChangeA(
    _In_ SC_HANDLE        hService,
    _In_ DWORD            dwNotifyMask,
    _In_ PSERVICE_NOTIFYA pNotifyBuffer);
typedef DWORD (WINAPI* PFN_NotifyServiceStatusChangeA)(
    _In_ SC_HANDLE        hService,
    _In_ DWORD            dwNotifyMask,
    _In_ PSERVICE_NOTIFYA pNotifyBuffer);
extern PFN_NotifyServiceStatusChangeA REAL_NotifyServiceStatusChangeA;

DWORD WINAPI HOOK_NotifyServiceStatusChangeW(
    _In_ SC_HANDLE        hService,
    _In_ DWORD            dwNotifyMask,
    _In_ PSERVICE_NOTIFYW pNotifyBuffer);
typedef DWORD (WINAPI* PFN_NotifyServiceStatusChangeW)(
    _In_ SC_HANDLE        hService,
    _In_ DWORD            dwNotifyMask,
    _In_ PSERVICE_NOTIFYW pNotifyBuffer);
extern PFN_NotifyServiceStatusChangeW REAL_NotifyServiceStatusChangeW;

BOOL WINAPI HOOK_EnumDependentServicesA(
    _In_            SC_HANDLE              hService,
    _In_            DWORD                  dwServiceState,
    _Out_opt_       LPENUM_SERVICE_STATUSA lpServices,
    _In_            DWORD                  cbBufSize,
    _Out_           LPDWORD                pcbBytesNeeded,
    _Out_           LPDWORD                lpServicesReturned);
typedef BOOL (WINAPI* PFN_EnumDependentServicesA)(
    _In_            SC_HANDLE              hService,
    _In_            DWORD                  dwServiceState,
    _Out_opt_       LPENUM_SERVICE_STATUSA lpServices,
    _In_            DWORD                  cbBufSize,
    _Out_           LPDWORD                pcbBytesNeeded,
    _Out_           LPDWORD                lpServicesReturned);
extern PFN_EnumDependentServicesA REAL_EnumDependentServicesA;

BOOL WINAPI HOOK_EnumDependentServicesW(
    _In_            SC_HANDLE              hService,
    _In_            DWORD                  dwServiceState,
    _Out_opt_       LPENUM_SERVICE_STATUSW lpServices,
    _In_            DWORD                  cbBufSize,
    _Out_           LPDWORD                pcbBytesNeeded,
    _Out_           LPDWORD                lpServicesReturned);
typedef BOOL (WINAPI* PFN_EnumDependentServicesW)(
    _In_            SC_HANDLE              hService,
    _In_            DWORD                  dwServiceState,
    _Out_opt_       LPENUM_SERVICE_STATUSW lpServices,
    _In_            DWORD                  cbBufSize,
    _Out_           LPDWORD                pcbBytesNeeded,
    _Out_           LPDWORD                lpServicesReturned);
extern PFN_EnumDependentServicesW REAL_EnumDependentServicesW;

BOOL WINAPI HOOK_EnumServicesStatusA(
    _In_                SC_HANDLE              hSCManager,
    _In_                DWORD                  dwServiceType,
    _In_                DWORD                  dwServiceState,
    _Out_opt_           LPENUM_SERVICE_STATUSA lpServices,
    _In_                DWORD                  cbBufSize,
    _Out_               LPDWORD                pcbBytesNeeded,
    _Out_               LPDWORD                lpServicesReturned,
    _Inout_opt_         LPDWORD                lpResumeHandle);
typedef BOOL (WINAPI* PFN_EnumServicesStatusA)(
    _In_                SC_HANDLE              hSCManager,
    _In_                DWORD                  dwServiceType,
    _In_                DWORD                  dwServiceState,
    _Out_opt_           LPENUM_SERVICE_STATUSA lpServices,
    _In_                DWORD                  cbBufSize,
    _Out_               LPDWORD                pcbBytesNeeded,
    _Out_               LPDWORD                lpServicesReturned,
    _Inout_opt_         LPDWORD                lpResumeHandle);
extern PFN_EnumServicesStatusA REAL_EnumServicesStatusA;

BOOL WINAPI HOOK_EnumServicesStatusW(
    _In_                SC_HANDLE              hSCManager,
    _In_                DWORD                  dwServiceType,
    _In_                DWORD                  dwServiceState,
    _Out_opt_           LPENUM_SERVICE_STATUSW lpServices,
    _In_                DWORD                  cbBufSize,
    _Out_               LPDWORD                pcbBytesNeeded,
    _Out_               LPDWORD                lpServicesReturned,
    _Inout_opt_         LPDWORD                lpResumeHandle);
typedef BOOL (WINAPI* PFN_EnumServicesStatusW)(
    _In_                SC_HANDLE              hSCManager,
    _In_                DWORD                  dwServiceType,
    _In_                DWORD                  dwServiceState,
    _Out_opt_           LPENUM_SERVICE_STATUSW lpServices,
    _In_                DWORD                  cbBufSize,
    _Out_               LPDWORD                pcbBytesNeeded,
    _Out_               LPDWORD                lpServicesReturned,
    _Inout_opt_         LPDWORD                lpResumeHandle);
extern PFN_EnumServicesStatusW REAL_EnumServicesStatusW;

BOOL WINAPI HOOK_EnumServicesStatusExA(
    _In_                SC_HANDLE    hSCManager,
    _In_                SC_ENUM_TYPE InfoLevel,
    _In_                DWORD        dwServiceType,
    _In_                DWORD        dwServiceState,
    _Out_opt_           LPBYTE       lpServices,
    _In_                DWORD        cbBufSize,
    _Out_               LPDWORD      pcbBytesNeeded,
    _Out_               LPDWORD      lpServicesReturned,
    _Inout_opt_         LPDWORD      lpResumeHandle,
    _In_opt_            LPCSTR       pszGroupName);
typedef BOOL (WINAPI* PFN_EnumServicesStatusExA)(
    _In_                SC_HANDLE    hSCManager,
    _In_                SC_ENUM_TYPE InfoLevel,
    _In_                DWORD        dwServiceType,
    _In_                DWORD        dwServiceState,
    _Out_opt_           LPBYTE       lpServices,
    _In_                DWORD        cbBufSize,
    _Out_               LPDWORD      pcbBytesNeeded,
    _Out_               LPDWORD      lpServicesReturned,
    _Inout_opt_         LPDWORD      lpResumeHandle,
    _In_opt_            LPCSTR       pszGroupName);
extern PFN_EnumServicesStatusExA REAL_EnumServicesStatusExA;

BOOL WINAPI HOOK_EnumServicesStatusExW(
    _In_                SC_HANDLE    hSCManager,
    _In_                SC_ENUM_TYPE InfoLevel,
    _In_                DWORD        dwServiceType,
    _In_                DWORD        dwServiceState,
    _Out_opt_           LPBYTE       lpServices,
    _In_                DWORD        cbBufSize,
    _Out_               LPDWORD      pcbBytesNeeded,
    _Out_               LPDWORD      lpServicesReturned,
    _Inout_opt_         LPDWORD      lpResumeHandle,
    _In_opt_            LPCWSTR      pszGroupName);
typedef BOOL (WINAPI* PFN_EnumServicesStatusExW)(
    _In_                SC_HANDLE    hSCManager,
    _In_                SC_ENUM_TYPE InfoLevel,
    _In_                DWORD        dwServiceType,
    _In_                DWORD        dwServiceState,
    _Out_opt_           LPBYTE       lpServices,
    _In_                DWORD        cbBufSize,
    _Out_               LPDWORD      pcbBytesNeeded,
    _Out_               LPDWORD      lpServicesReturned,
    _Inout_opt_         LPDWORD      lpResumeHandle,
    _In_opt_            LPCWSTR      pszGroupName);
extern PFN_EnumServicesStatusExW REAL_EnumServicesStatusExW;

BOOL WINAPI HOOK_GetServiceDisplayNameA(
    _In_            SC_HANDLE               hSCManager,
    _In_            LPCSTR                lpServiceName,
    _Out_writes_opt_(*lpcchBuffer)
    LPSTR                 lpDisplayName,
    _Inout_         LPDWORD                 lpcchBuffer);
typedef BOOL (WINAPI* PFN_GetServiceDisplayNameA)(
    _In_            SC_HANDLE               hSCManager,
    _In_            LPCSTR                lpServiceName,
    _Out_writes_opt_(*lpcchBuffer)
    LPSTR                 lpDisplayName,
    _Inout_         LPDWORD                 lpcchBuffer);
extern PFN_GetServiceDisplayNameA REAL_GetServiceDisplayNameA;

BOOL WINAPI HOOK_GetServiceDisplayNameW(
    _In_            SC_HANDLE               hSCManager,
    _In_            LPCWSTR                lpServiceName,
    _Out_writes_opt_(*lpcchBuffer)
    LPWSTR                 lpDisplayName,
    _Inout_         LPDWORD                 lpcchBuffer);
typedef BOOL (WINAPI* PFN_GetServiceDisplayNameW)(
    _In_            SC_HANDLE               hSCManager,
    _In_            LPCWSTR                lpServiceName,
    _Out_writes_opt_(*lpcchBuffer)
    LPWSTR                 lpDisplayName,
    _Inout_         LPDWORD                 lpcchBuffer);
extern PFN_GetServiceDisplayNameW REAL_GetServiceDisplayNameW;

BOOL WINAPI HOOK_GetServiceKeyNameA(
    _In_            SC_HANDLE hSCManager,
    _In_            LPCSTR    lpDisplayName,
    _Out_opt_       LPSTR     lpServiceName,
    _Inout_         LPDWORD   lpcchBuffer);
typedef BOOL (WINAPI* PFN_GetServiceKeyNameA)(
    _In_            SC_HANDLE hSCManager,
    _In_            LPCSTR    lpDisplayName,
    _Out_opt_       LPSTR     lpServiceName,
    _Inout_         LPDWORD   lpcchBuffer);
extern PFN_GetServiceKeyNameA REAL_GetServiceKeyNameA;

BOOL WINAPI HOOK_GetServiceKeyNameW(
    _In_            SC_HANDLE hSCManager,
    _In_            LPCWSTR   lpDisplayName,
    _Out_opt_       LPWSTR    lpServiceName,
    _Inout_         LPDWORD   lpcchBuffer);
typedef BOOL (WINAPI* PFN_GetServiceKeyNameW)(
    _In_            SC_HANDLE hSCManager,
    _In_            LPCWSTR   lpDisplayName,
    _Out_opt_       LPWSTR    lpServiceName,
    _Inout_         LPDWORD   lpcchBuffer);
extern PFN_GetServiceKeyNameW REAL_GetServiceKeyNameW;

BOOL WINAPI HOOK_StartServiceCtrlDispatcherA(_In_ CONST  SERVICE_TABLE_ENTRYA* lpServiceStartTable);
typedef BOOL (WINAPI* PFN_StartServiceCtrlDispatcherA)(_In_ CONST  SERVICE_TABLE_ENTRYA* lpServiceStartTable);
extern PFN_StartServiceCtrlDispatcherA REAL_StartServiceCtrlDispatcherA;

BOOL WINAPI HOOK_StartServiceCtrlDispatcherW(_In_ CONST  SERVICE_TABLE_ENTRYW* lpServiceStartTable);
typedef BOOL (WINAPI* PFN_StartServiceCtrlDispatcherW)(_In_ CONST  SERVICE_TABLE_ENTRYW* lpServiceStartTable);
extern PFN_StartServiceCtrlDispatcherW REAL_StartServiceCtrlDispatcherW;

DWORD WINAPI HOOK_GetServiceDirectory(
    SERVICE_STATUS_HANDLE  hServiceStatus,
    SERVICE_DIRECTORY_TYPE eDirectoryType,
    PWCHAR                 lpPathBuffer,
    DWORD                  cchPathBufferLength,
    DWORD* lpcchRequiredBufferLength);
typedef DWORD (WINAPI* PFN_GetServiceDirectory)(
    SERVICE_STATUS_HANDLE  hServiceStatus,
    SERVICE_DIRECTORY_TYPE eDirectoryType,
    PWCHAR                 lpPathBuffer,
    DWORD                  cchPathBufferLength,
    DWORD* lpcchRequiredBufferLength);
extern PFN_GetServiceDirectory REAL_GetServiceDirectory;

DWORD WINAPI HOOK_GetServiceRegistryStateKey(
    SERVICE_STATUS_HANDLE       ServiceStatusHandle,
    SERVICE_REGISTRY_STATE_TYPE StateType,
    DWORD                       AccessMask,
    HKEY* ServiceStateKey);
typedef DWORD (WINAPI* PFN_GetServiceRegistryStateKey)(
    SERVICE_STATUS_HANDLE       ServiceStatusHandle,
    SERVICE_REGISTRY_STATE_TYPE StateType,
    DWORD                       AccessMask,
    HKEY* ServiceStateKey);
extern PFN_GetServiceRegistryStateKey REAL_GetServiceRegistryStateKey;

DWORD WINAPI HOOK_GetSharedServiceDirectory(
    SC_HANDLE                     ServiceHandle,
    SERVICE_SHARED_DIRECTORY_TYPE DirectoryType,
    PWCHAR                        PathBuffer,
    DWORD                         PathBufferLength,
    DWORD* RequiredBufferLength);
typedef DWORD (WINAPI* PFN_GetSharedServiceDirectory)(
    SC_HANDLE                     ServiceHandle,
    SERVICE_SHARED_DIRECTORY_TYPE DirectoryType,
    PWCHAR                        PathBuffer,
    DWORD                         PathBufferLength,
    DWORD* RequiredBufferLength);
extern PFN_GetSharedServiceDirectory REAL_GetSharedServiceDirectory;

DWORD WINAPI HOOK_GetSharedServiceRegistryStateKey(
    SC_HANDLE                          ServiceHandle,
    SERVICE_SHARED_REGISTRY_STATE_TYPE StateType,
    DWORD                              AccessMask,
    HKEY* ServiceStateKey);
typedef DWORD (WINAPI* PFN_GetSharedServiceRegistryStateKey)(
    SC_HANDLE                          ServiceHandle,
    SERVICE_SHARED_REGISTRY_STATE_TYPE StateType,
    DWORD                              AccessMask,
    HKEY* ServiceStateKey);
extern PFN_GetSharedServiceRegistryStateKey REAL_GetSharedServiceRegistryStateKey;

SC_LOCK WINAPI HOOK_LockServiceDatabase(_In_ SC_HANDLE hSCManager);
typedef SC_LOCK (WINAPI* PFN_LockServiceDatabase)(_In_ SC_HANDLE hSCManager);
extern PFN_LockServiceDatabase REAL_LockServiceDatabase;

BOOL WINAPI HOOK_NotifyBootConfigStatus(_In_ BOOL BootAcceptable);
typedef BOOL (WINAPI* PFN_NotifyBootConfigStatus)(_In_ BOOL BootAcceptable);
extern PFN_NotifyBootConfigStatus REAL_NotifyBootConfigStatus;

BOOL WINAPI HOOK_QueryServiceDynamicInformation(
    _In_ SERVICE_STATUS_HANDLE hServiceStatus,
    _In_ DWORD                 dwInfoLevel,
    PVOID* ppDynamicInfo);
typedef BOOL (WINAPI* PFN_QueryServiceDynamicInformation)(
    _In_ SERVICE_STATUS_HANDLE hServiceStatus,
    _In_ DWORD                 dwInfoLevel,
    PVOID* ppDynamicInfo);
extern PFN_QueryServiceDynamicInformation REAL_QueryServiceDynamicInformation;

BOOL WINAPI HOOK_QueryServiceStatus(
    _In_  SC_HANDLE        hService,
    _Out_ LPSERVICE_STATUS lpServiceStatus);
typedef BOOL (WINAPI* PFN_QueryServiceStatus)(
    _In_  SC_HANDLE        hService,
    _Out_ LPSERVICE_STATUS lpServiceStatus);
extern PFN_QueryServiceStatus REAL_QueryServiceStatus;

BOOL WINAPI HOOK_QueryServiceStatusEx(
    _In_            SC_HANDLE      hService,
    _In_            SC_STATUS_TYPE InfoLevel,
    _Out_opt_       LPBYTE         lpBuffer,
    _In_            DWORD          cbBufSize,
    _Out_           LPDWORD        pcbBytesNeeded);
typedef BOOL (WINAPI* PFN_QueryServiceStatusEx)(
    _In_            SC_HANDLE      hService,
    _In_            SC_STATUS_TYPE InfoLevel,
    _Out_opt_       LPBYTE         lpBuffer,
    _In_            DWORD          cbBufSize,
    _Out_           LPDWORD        pcbBytesNeeded);
extern PFN_QueryServiceStatusEx REAL_QueryServiceStatusEx;

BOOL WINAPI HOOK_QueryServiceObjectSecurity(
    _In_            SC_HANDLE            hService,
    _In_            SECURITY_INFORMATION dwSecurityInformation,
    _Out_opt_       PSECURITY_DESCRIPTOR lpSecurityDescriptor,
    _In_            DWORD                cbBufSize,
    _Out_           LPDWORD              pcbBytesNeeded);
typedef BOOL (WINAPI* PFN_QueryServiceObjectSecurity)(
    _In_            SC_HANDLE            hService,
    _In_            SECURITY_INFORMATION dwSecurityInformation,
    _Out_opt_       PSECURITY_DESCRIPTOR lpSecurityDescriptor,
    _In_            DWORD                cbBufSize,
    _Out_           LPDWORD              pcbBytesNeeded);
extern PFN_QueryServiceObjectSecurity REAL_QueryServiceObjectSecurity;

BOOL WINAPI HOOK_SetServiceObjectSecurity(
    _In_ SC_HANDLE            hService,
    _In_ SECURITY_INFORMATION dwSecurityInformation,
    _In_ PSECURITY_DESCRIPTOR lpSecurityDescriptor);
typedef BOOL (WINAPI* PFN_SetServiceObjectSecurity)(
    _In_ SC_HANDLE            hService,
    _In_ SECURITY_INFORMATION dwSecurityInformation,
    _In_ PSECURITY_DESCRIPTOR lpSecurityDescriptor);
extern PFN_SetServiceObjectSecurity REAL_SetServiceObjectSecurity;

BOOL WINAPI HOOK_ControlService(
    _In_        SC_HANDLE           hService,
    _In_        DWORD               dwControl,
    _Out_       LPSERVICE_STATUS    lpServiceStatus);
typedef BOOL (WINAPI* PFN_ControlService)(
    _In_        SC_HANDLE           hService,
    _In_        DWORD               dwControl,
    _Out_       LPSERVICE_STATUS    lpServiceStatus);
extern PFN_ControlService REAL_ControlService;

BOOL WINAPI HOOK_SetServiceStatus(
    _In_ SERVICE_STATUS_HANDLE hServiceStatus,
    _In_ LPSERVICE_STATUS      lpServiceStatus);
typedef BOOL (WINAPI* PFN_SetServiceStatus)(
    _In_ SERVICE_STATUS_HANDLE hServiceStatus,
    _In_ LPSERVICE_STATUS      lpServiceStatus);
extern PFN_SetServiceStatus REAL_SetServiceStatus;

BOOL WINAPI HOOK_DeleteService(_In_        SC_HANDLE   hService);
typedef BOOL (WINAPI* PFN_DeleteService)(_In_        SC_HANDLE   hService);
extern PFN_DeleteService REAL_DeleteService;

BOOL WINAPI HOOK_CloseServiceHandle(_In_        SC_HANDLE   hSCObject);
typedef BOOL(WINAPI* PFN_CloseServiceHandle)(_In_        SC_HANDLE   hSCObject);
extern PFN_CloseServiceHandle REAL_CloseServiceHandle;

#endif